/**
 在 JavaScript 的响应式系统中，依赖收集是实现数据变化时自动更新视图的关键机制。在 Vue 3 中，依赖收集主要通过  `Proxy`  和  `reactive`  API 来实现。以下是对响应式依赖收集的说明总结：

  1. 依赖收集的基本概念
  - 依赖收集：当一个响应式对象的属性被访问时，系统会记录下这个访问者（通常是组件或计算属性）。当这个属性发生变化时，所有依赖于它的访问者都会被通知并重新渲染。
  - 依赖收集的目的是确保视图始终与状态保持同步，从而实现响应式更新。

  2. 使用 Proxy 实现依赖收集
  Vue 3 利用  `Proxy`  对对象进行代理，从而拦截对对象属性的访问和修改。具体流程如下：

  - getter：当访问一个属性时， `getter`  会被调用。在这个过程中，Vue 会记录当前的依赖（即访问这个属性的组件或计算属性）。
  - setter：当属性值发生变化时， `setter`  会被调用。此时，Vue 会触发所有依赖于这个属性的更新。

  3. 依赖的注册与通知
  - 注册依赖：在访问响应式属性时，Vue 会将当前的依赖（如组件实例或计算属性）注册到该属性的依赖列表中。
  - 通知更新：在属性值改变时，Vue 会遍历该属性的依赖列表，并调用所有依赖的更新函数，从而触发视图更新。

  4. 示例
  以下是一个简单的示例，展示了如何使用 Vue 3 的响应式系统进行依赖收集：
  import { reactive, effect } from 'vue';

  const state = reactive({ count: 0 });

  // 定义一个响应式的效果
  effect(() => {
    console.log(`Count is: ${state.count}`);
  });

  // 修改响应式数据
  state.count++; // 当 count 变化时，依赖会被通知并打印新的值
  5. 依赖收集的优化
  - Vue 3 在依赖收集时采用了懒惰收集的策略，只有在属性被访问时才会进行依赖注册，从而减少不必要的依赖。
  - 通过  `effect`  函数，用户可以定义响应式的副作用，Vue 会自动管理依赖的注册与更新。

  总结
  依赖收集是 Vue 3 响应式系统的核心机制，通过  `Proxy`  实现对对象属性的访问和修改拦截，从而实现数据和视图的自动同步。理解依赖收集的工作原理有助于开发者更好地利用 Vue 的响应式特性，提高应用的性能和用户体验。
 */

  const obj = {
    name: 'responsive',
    age: 18
  }

  // function foo() {
  //   console.log("foo:", obj.name)
  //   console.log("foo", obj.age)
  //   console.log("foo function")
  // }

  // function bar() {
  //   console.log("bar:", obj.name + " hello")
  //   console.log("bar:", obj.age + 10)
  //   console.log("bar function")
  // }

  // 设置一个专门执行响应式函数的一个函数
  const reactiveFns = []
  function effect(fn) {
    // 将传入的函数保存到数组中
    reactiveFns.push(fn)
    // 执行函数
    fn()
  }

  function foo() {
    console.log("foo:", obj.name)
    console.log("foo", obj.age)
    console.log("foo function")
  }

  function bar() {
    console.log("bar:", obj.name + " hello")
    console.log("bar:", obj.age + 10)
    console.log("bar function")
  }

  effect(foo)
  effect(bar)


  // 修改响应式数据
  obj.name = "reactive-name"
  obj.age = 20

  // 遍历数组，执行函数
  reactiveFns.forEach(fn => fn())